#include "skia_control/button.h"

#include <include/core/SkCanvas.h>

#include "skia_framework.h"

namespace SkiaControl {
Button::Builder::Builder()
{
    buildingButton_ = std::shared_ptr<Button>(new Button());
}

void Button::Builder::SetRegion(const SkRect &region)
{
    buildingButton_->region_ = region;
}

void Button::Builder::SetColor(const SkColor &color)
{
    buildingButton_->color_ = color;
}

void Button::Builder::SetText(const std::string &text)
{
    buildingButton_->text_ = text;
}

std::shared_ptr<Button> Button::Builder::Build()
{
    return buildingButton_;
}

bool Button::IsContain(int32_t x, int32_t y)
{
    auto wh = SkiaFramework::MeasureString(text_);
    auto region = region_;
    if (region.width() == 0) {
        region.fRight = region.fLeft + wh.x();
    }
    if (region_.height() == 0) {
        region.fBottom = region.fTop + wh.y();
    }
    return region.contains(x, y);
}

void Button::OnMouseMotion(int32_t x, int32_t y)
{
    SkiaControlHover::OnMouseMotion(x, y);
    SkiaControlBase::OnMouseMotion(x, y);
}

void Button::OnMouseDown(int32_t x, int32_t y)
{
    SkiaControlDown::OnMouseDown(x, y);
    SkiaControlBase::OnMouseDown(x, y);
}

void Button::OnMouseUp()
{
    SkiaControlDown::OnMouseUp();
    SkiaControlBase::OnMouseUp();
}

void Button::OnClick(int32_t x, int32_t y)
{
    SkiaControlBase::OnClick(x, y);

    if (onClick_ != nullptr) {
        onClick_();
    }
}

void Button::OnDraw(SkCanvas &canvas)
{
    SkiaControlBase::OnDraw(canvas);

    auto wh = SkiaFramework::MeasureString(text_);
    auto region = region_;
    if (region.width() == 0) {
        region.fRight = region.fLeft + wh.x();
    }
    if (region.height() == 0) {
        region.fBottom = region.fTop + wh.y();
    }

    SkPoint offset{region.width() - wh.x(), region.height() - wh.y()};
    offset.scale(0.5);

    SkPaint paint;
    paint.setAntiAlias(true);

    paint.setColor(color_);
    paint.setStyle(paint.kFill_Style);
    if (IsDown()) {
        paint.setARGB(0xff,
            SkColorGetR(color_) * 0x9f / 0xff,
            SkColorGetG(color_) * 0x9f / 0xff,
            SkColorGetB(color_) * 0x9f / 0xff);
        canvas.drawRect(region, paint);
    } else if (IsHover()) {
        paint.setARGB(0xff,
            SkColorGetR(color_) * 0x9f / 0xff + 0x60,
            SkColorGetG(color_) * 0x9f / 0xff + 0x60,
            SkColorGetB(color_) * 0x9f / 0xff + 0x60);
        canvas.drawRect(region, paint);
    } else {
        canvas.drawRect(region, paint);
    }

    paint.setColor(SK_ColorBLACK);
    paint.setStyle(paint.kStroke_Style);
    canvas.drawRect(region, paint);

    double gray = SkColorGetR(color_) * 0.299 + SkColorGetG(color_) * 0.587 + SkColorGetB(color_) * 0.114;
    paint.setColor(gray / 256.0 >= 0.5 ? SK_ColorBLACK : SK_ColorWHITE);
    paint.setStroke(paint.kFill_Style);
    SkiaFramework::DrawString(canvas, text_, region.x() + offset.x(), region.y() + offset.y() + wh.z());
}
} // namespace SkiaControl
